﻿using System;
using RBT;

namespace RBTreesSample
{
    sealed class Program
    {
        private static RBTree _rbTree = new RBTree();

        static public void Main()
        {
            try
            {
                /*Console.Write("Enter # of objects: ");
                var xObjects = int.Parse(Console.ReadLine());
                OwnObject ownObject;
                OwnKey ownKey;
                for (var i = 0; i < xObjects - 1; i++)
                {
                    ownObject = new OwnObject(i, DateTime.Now.ToLocalTime().ToString());
                    ownKey = new OwnKey(ownObject.Key);
                    _rbTree.Add(ownKey, ownObject);
                }*/

                _rbTree.Add(new OwnKey(10), "--1");
                _rbTree.Add(new OwnKey(8), "--2");
                _rbTree.Add(new OwnKey(12), "--3");
                _rbTree.Add(new OwnKey(14), "--4");
                _rbTree.Add(new OwnKey(7), "--5");
                
                TraverseEnumerator();

                Console.WriteLine("* Root\n\tKey: {0}", _rbTree.GetRoot().Key);
                

                Console.WriteLine("\n\n* RB Tree Values");
                var tempData = _rbTree.Values();
                while (tempData.MoveNext())
                    Console.WriteLine(tempData.Value);

                Console.WriteLine("\n\n* RedBlack Keys");
                var tempKeys = _rbTree.Keys();
                while (tempKeys.MoveNext())
                    Console.WriteLine(tempKeys.Key);

                DumpMinMaxValues();

                var tObjKey = (OwnKey)_rbTree.GetMinKey();
                var tObj = _rbTree.GetData(tObjKey);
                Console.WriteLine("\n* Remove Min Key: {0}", tObj);
                _rbTree.Remove(tObjKey);
                DumpRB(false);

                Console.WriteLine("\n\n* Remove Max Value: {0}", _rbTree.GetMaxValue());
                _rbTree.RemoveMax();
                Console.WriteLine("\n* Remove Min Value: {0}", _rbTree.GetMinValue());
                _rbTree.RemoveMin();
                DumpRB(true);
                Console.WriteLine("\n* Remove Min Key: {0}", _rbTree.GetMinKey());
                _rbTree.RemoveMin();
                Console.WriteLine("\n* Remove Max Key: {0}", _rbTree.GetMaxKey());
                _rbTree.RemoveMax();

                DumpRB(true);

                /*Console.WriteLine("\n\n* Clearing Tree");
                _rbTree.Clear();

                DumpRB(false);
                */

                Console.Write("\n\n\nPress enter to terminate...");
                Console.ReadLine();

            }
            catch (Exception ex)
            {
                Console.WriteLine("\n\n{0}", ex.Message);
                Console.WriteLine("\n\nPress enter to terminate...");
                Console.ReadLine();
            }
        }

        public static void DumpRB(bool boolDesc)
        {
            // returns keys only
            var keys = _rbTree.Keys(boolDesc);
            // returns data only, in this case
            var elements = _rbTree.Elements(boolDesc);
            Console.WriteLine(boolDesc ? "\n* Dumping RedBlack: Ascending" : "\n* Dumping RedBlack: Descending");
            Console.WriteLine("* RB Tree Size: {0}", _rbTree.Size());
            Console.WriteLine("\n* Keys");
            while (keys.HasMoreElements())
                Console.WriteLine("\t{0}", keys.NextElement());
            Console.WriteLine("\n* Objects");
            while (elements.HasMoreElements())
            {
                Console.WriteLine("\tData: {0}", elements.NextElement());
            }
        }

        public static void TraverseEnumerator()
        {
            Console.WriteLine("* Traversing using Enumerator");
            var myEnumerator = _rbTree.GetEnumerator();
            var parent = "";
            while (myEnumerator.MoveNext())
            {
                parent = myEnumerator.ParentKey == null 
                    ? "null" : myEnumerator.ParentKey.ToString();
                Console.WriteLine("\tKey: {0}\tData: {1}\tColor: {2}\tParent Key: {3}",
                    myEnumerator.Key, myEnumerator.Value, myEnumerator.Color, myEnumerator.ParentKey);
            }
        }

        public static void DumpMinMaxValues()
        {
            Console.WriteLine("\n* Dumping Min/Max Values");
            Console.WriteLine("\tMin object value: {0}", 
                _rbTree.GetMinValue());
            Console.WriteLine("\tMax object value: {0}",
                _rbTree.GetMaxValue());
            Console.WriteLine("\tMin object key: {0}", _rbTree.GetMinKey());
            Console.WriteLine("\tMax object key: {0}", _rbTree.GetMaxKey());
        }
    }
}
